class Calculation
  def get_calculation_inputs
  end

  def get_calculation_actual_result(inputs)
  end

  def score_result(inputs, actual, calculated)
    score = (calculated - actual).abs.to_f / actual.to_f
    return score
  end

  def run_calculation(machine, opts = {})
    unless opts[:reset_calculation] == false
      machine.reset_computation
    end

    inputs = get_calculation_inputs
    inputs.each_index do |i|
      input = inputs[i]
      machine.registers[i] = input
    end

    result_register = opts[:result_register] || 0

    machine.run_computation

    result = machine.registers[result_register]

    actual = get_calculation_actual_result(inputs) || 0
    score = score_result(inputs, actual, result)
    machine.save_score(score)

    if score == 0
      puts "SCORE 0! #{inputs.inspect} #{actual.inspect} #{result.inspect}: #{machine.scores.inspect}"
    end

    return score
  end
end
